package finder;

import finder.filters.LinkFilter;
import finder.filters.RegexFilter;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

/**
 *
 * @author Alex
 */
public class Finder 
{
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) 
    {
        String url = "";
        FilterDescription filter = new FilterDescription();
        FilterStage stage = new FilterStage(new LinkFilter());
        boolean linkable = false;
        int group = 0;
        int mode = 0;
        
        for(int x = 0; x < args.length; x++)
        {
            if(x == args.length - 1)
            {
                url = args[x];
                try 
                {
                    URL u = new URL(url);
                    if(!u.toURI().isAbsolute())
                        throw new MalformedURLException();
                } 
                catch (MalformedURLException | URISyntaxException ex) 
                {
                    System.out.println("Invalid URL.");
                    return;
                }
            }
            else
            {
                if(args[x].length() > 1 && args[x].startsWith("/"))
                {
                    switch(Character.toLowerCase(args[x].charAt(1)))
                    {
                        case '?':
                            System.out.println(getUsage());
                            return;
                        case 'p':
                            linkable = false;
                            mode = 1;
                            break;
                        case 's':
                            mode = 2;
                            break;
                        case 'l':
                            if(mode == 1)
                                linkable = true;
                            else
                            {
                                System.out.println(getUsageError() + getUsage());
                                return;
                            }
                            break;
                    }
                }
                else
                {
                    if(mode == 1 || mode == 2)
                    {
                        if(args[x].startsWith("\"") && args[x].endsWith("\""))
                        {//its a regex
                            String pattern = args[x].substring(1, args[x].length() - 1);
                            if(mode == 1)
                            {
                                stage = new FilterStage(new RegexFilter(pattern,group,linkable));
                                filter.getStages().add(stage);
                            }
                            else
                                stage.addSecondaryStage(new RegexFilter(pattern,group,false));
                            mode = 0;
                        }
                        else
                        {//its a group
                            try
                            {
                                group = Integer.parseInt(args[x]);
                            }
                            catch (NumberFormatException ex)
                            {
                                System.out.println(getUsageError() + getUsage());
                                return;
                            }
                        }
                    }
                    else
                    {
                        System.out.println(getUsageError() + getUsage());
                        return;
                    }
                }
            }
        }
        if(url.equals(""))
        {
            System.out.println(getUsageError() + getUsage());
            return;
        }
        if(filter.getStages().isEmpty())
            filter.getStages().add(stage);
        
        System.out.print(getString(filter.find(url)));
    }
    public static String[] find(FilterDescription filter, String url)
    {
        List<String> list = filter.find(url);
        return list.toArray(new String[list.size()]);
    }
    private static String getString(List<String> list)
    {
        StringBuilder sbuild = new StringBuilder();
        for(String s : list)
            sbuild.append(s).append("\n");
        return sbuild.toString();
    }
    private static String combineStrings(String[] array)
    {
        StringBuilder sbuild = new StringBuilder();
        for(int x =0; x < array.length;x++)
            sbuild.append(array[x]);
        return sbuild.toString();
    }
    private static String getUsageError()
    {
        return "Error: Incomplete or unrecognized command.\n";
    }
    private static String getUsage()
    {
        String usage = "Usage:\n";
        usage += "   finder [/?] [/P [/L] [group] \"regex\"] [/S [group] \"regex\"] url\n\n";
        usage += "group\t The group in the regex you are interested in matching.\n";
        usage += "regex\t A regular expression enclosed in quotes: \"regex\".\n";
        usage += "url\t Specifies a valid URL to a text based resource.\n";
        usage += "/P\t Adds a PrimaryFilter stage.\n";
        usage += "/L\t Marks a filter as one that produces links.\n";
        usage += "/S\t Adds a SecondaryFilter stage.\n\n";
        usage += "Example:\n";
        usage += "  finder /p \"<[^<>]+>\" /s \".*meta.*\" http://www.google.com\n";
        usage += "This finds all meta tags on the google home page.\n\n";
        usage += "GUIDE:\n";
        usage += "Primary filters are used to find elements from raw textual "
                + "content like the initial url provided. Secondary filters "
                + "are used to reduce the number of matches found in the primary"
                + "filter. Only results filtered by all secondary filter are kept and"
                + "multiple secondary filters can occure after a single primary "
                + "filter. If no filters are provided a default primary filter will"
                + "be used to find links on the url provided. Specifying a group"
                + " is optional, but allows you to control which part of the regex is"
                + " returned. If no group is provided the entire match will be returned."
                + " Multiple primary filters are allowed, but only if the preceeding "
                + "returns a linkable input.";
        return usage;
    }    
}